function out = GausTrainer( InitData ,dataSample, Rules,...
  Params )

  rulesCount = size(Rules,1);
  
  values = zeros(InitData.FeatureCount, 1);
  RulleActivation = zeros(rulesCount, 2);
  
  sigma = InitData.Sigma;
  
  min_error = 100;
  prev_error = 100;
  
  error = 1;
  iter = 0;
  
  max_repeats = 20;
  repeats = 0;
  
  while(error > InitData.MaxError && iter < InitData.MaxEpouch && ...
      repeats < max_repeats)
    
      %Start Epoch
    for i=1: InitData.LearnCount
      for j=1:rulesCount
        for k =1: InitData.FeatureCount
          values(k) = InitData.FuzzySetHandler(dataSample(i,k), Params(Rules(j,k),:,k));
        end%for k
        %[value, index]
        [RulleActivation(j,1),RulleActivation(j,2)] = min(values);
        RulleActivation(j,1) = prod(values);
      end%for j

      [~,index] = max(RulleActivation(:,1));

      resultClass = Rules(index,end);
      etalonClass = dataSample(i, end);
      
      if(etalonClass ~= resultClass)
        diff =  1; %etalonClass - resultClass;
        for j=1:rulesCount      
          param = Params(Rules(j,RulleActivation(j,2)),:,RulleActivation(j,2));
          x = dataSample(i,RulleActivation(j,2));
          delta_a= 2 * 0.01 * diff * RulleActivation(j,1) * (x - param(1)) / param(2)^2;
          delta_b= 2 * 0.02 * diff * RulleActivation(j,1) * (x - param(1))^2 / param(2)^3;
          %[0.01 ,0.02]
          Params(Rules(j,RulleActivation(j,2)),:,RulleActivation(j,2)) = ...
            param + [delta_a  delta_b];
        end%for j
      end%if
    end %for i
    %End Epoch
  
  error = 0;
  
  for i=1: InitData.LearnCount
    for j=1:rulesCount
      for k =1: InitData.FeatureCount
        values(k) = InitData.FuzzySetHandler(dataSample(i,k), Params(Rules(j,k),:,k));
      end%for k
      %[value, index]
      [RulleActivation(j,1),RulleActivation(j,2)] = min(values);
    end%for j
    [~,index] = max(RulleActivation);
    
    resultClass = Rules(index,end);
    etalonClass = dataSample(i, end);
    
    if (etalonClass ~= resultClass)
      error = error + 1;
    end
  end %for i
  
  error = error / InitData.LearnCount;
  
  if(min_error > error)
     min_error = error;
    if (InitData.IsSafeState)
      Params_clone = Params;
    end
  end
  
  if (abs(prev_error - error) < 0.0001)
    repeats = repeats + 1;
    if (InitData.IsDynamicStep)
      sigma = sigma + InitData.Sigma;
    end
  else    
    repeats = 0;
    if (InitData.IsDynamicStep)
      sigma = sigma - InitData.Sigma;
    end
  end
  
  prev_error = error;
  
  iter = iter + 1;
    
  end%while
  
  fprintf('Min_error: %.8f\n', min_error);
  fprintf('Error on exit: %.8f\n', error);
  
  if (InitData.IsSafeState)
    Params = Params_clone; 
  end
  
  out = Params;
  
end

